# -*- coding: utf-8 -*-
# @Time : 2019/6/4 10:02
# @Author : Fioman
# @Phone : 13149920693
from ctypes import *
import gevent
from tools.hd_logger import HdLogger
from settings import *
from db_tools.db_handler import DbHandler


# 底层做了刹车保护，必须3秒内反转一下底层的bit（200）


class MainZmc(object):
    err_msg = ""

    def __init__(self):
        self.hRobot = c_longlong(0)
        self.lock = False
        self.ip = "192.168.0.16"
        self.logger = HdLogger()
        self.db = DbHandler()
        self.err_msg = ''
        try:
            self.api = cdll.LoadLibrary(ZMC_LIB_PATH)
            self.aux_api = cdll.LoadLibrary(AUX_ZMC_LIB_PATH)
        except Exception as e:
            self.api = None
            self.err_msg = str(e)
            print("in Zmc_init()  error: {}".format(e))
            self.logger.debug("in Zmc_init(), error: {}".format(e))

    def __del__(self):
        try:
            self.Close()
        except Exception as e:
            print("in Zmc_del()  error: {}".format(e))
            self.logger.debug("in Zmc_del(), error: {}".format(e))
            pass

    # 设置物料去向为平板1小车
    def set_to_flat(self):
        ret = self.set_modbus_bit(50, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(50, 1)
            if ret != 0:
                self.err_msg = "in set_to_flat() set main_zmc bit(25) failed!"
                return self.err_msg
        ret1 = self.set_modbus_bit(51, 0)
        if ret1 != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret1 = self.set_modbus_bit(51, 0)
            if ret1 != 0:
                self.err_msg = "in set_to_lv() set main_zmc bit(24) failed!"
                return self.err_msg
        return 0

    # 设置物料去向为平板车2
    def set_to_lv(self):
        ret = self.set_modbus_bit(50, 0)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(50, 0)
            if ret != 0:
                self.err_msg = "in set_to_flat() set main_zmc bit(25) failed!"
                return self.err_msg
        ret1 = self.set_modbus_bit(51, 1)
        if ret1 != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret1 = self.set_modbus_bit(51, 1)
            if ret1 != 0:
                self.err_msg = "in set_to_lv() set main_zmc bit(24) failed!"
                return self.err_msg
        return 0

    # 视觉允许一号相机拍照的信号
    def get_allow_take_pic(self):
        ret, val = self.get_modbus_bit(15, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(15, 1)
            if ret != 0:
                self.err_msg = "in get_allow_take_pic() get main_zmc(15) failed!"
                return -1, self.err_msg
        return 0, val[0]

    # 重新检测信号
    def set_allow_take_pic(self):
        ret1 = self.set_modbus_bit(15, 1)
        if ret1 != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret1 = self.set_modbus_bit(15, 1)
            if ret1 != 0:
                self.err_msg = "in set_allow_take_pic() set main_zmc bit(15) failed!"
                return self.err_msg
        return ret1

    # 清除允许拍照的bit位
    def set_allow_tabke_pic_clear(self):
        ret = self.set_modbus_bit(15, 0)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(15, 0)
            if ret != 0:
                self.err_msg = "in set_allow_tabke_pic_clear() set cutter_zmc bit(15) failed!"
                return self.err_msg
        return ret

    # 设置视觉检测ok
    def set_check_ok_1(self):
        ret = self.set_modbus_bit(19, 1)
        if ret != 0:
            # 重新尝试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(19, 1)
            if ret != 0:
                self.err_msg = "in set_check_ok() set main_zmc bit(19)=1 failded"
                return self.err_msg
        return ret

    # 设置视觉检测NG
    def set_check_failed_1(self):
        ret = self.set_modbus_bit(20, 1)
        if ret != 0:
            # 重新尝试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(20, 1)
            if ret != 0:
                self.err_msg = "in set_check_failed() set main_zmc bit(20)=1 failed "
                return self.err_msg
        return ret

    # 设置板到中心的偏移值
    def set_mid_offset_1(self, offset):
        if offset > 172:
            offset = 172
        if offset < -172:
            offset = -172
        ret = self.set_modbus_long(500, 1, [int(offset + 172)])
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_long(100, 1, [int(offset + 172)])
            if ret != 0:
                self.err_msg = "in set_mid_offset() set main_zmc modbus_ieee(100) failed!"
                return self.err_msg
        return ret

    def set_catch_pos_x(self, x):
        ieeePos = 0
        ret = self.set_modbus_long(ieeePos, 1, [x])
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_long(ieeePos, 1, [x])
            if ret != 0:
                self.err_msg = "in set_board_height() set main_zmc modbus_ieee(122) failed!"
                return self.err_msg
        return ret

    def set_catch_pos_y(self, y):
        ieeePos = 2
        ret = self.set_modbus_long(ieeePos, 1, [y])
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_long(ieeePos, 1, [y])
            if ret != 0:
                self.err_msg = "in set_board_height() set main_zmc modbus_ieee(122) failed!"
                return self.err_msg
        return ret

    def set_adjust_angle(self, angle):
        ieeePos = 6
        ret = self.set_modbus_long(ieeePos, 1, [angle])
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_long(ieeePos, 1, [angle])
            if ret != 0:
                self.err_msg = "in set_board_height() set main_zmc modbus_ieee(122) failed!"
                return self.err_msg
        return ret

    # 设置板的高度值
    def set_board_height(self, boardHeight):
        ret = self.set_modbus_float(102, 1, [boardHeight])
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_float(102, 1, [boardHeight])
            if ret != 0:
                self.err_msg = "in set_board_height() set main_zmc modbus_ieee(122) failed!"
                return self.err_msg
        return ret

    # 设置平板车1已完成计数
    def set_flat_board_finished(self, finished):
        ret = self.set_modbus_float(116, 1, [finished])
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_float(116, 1, [finished])
            if ret != 0:
                self.err_msg = "in set_flat_board_finished() set main_zmc modbus_ieee(117) failed!"
                return self.err_msg
        return ret

    # 设置平板车放板高度
    def set_flat_board_max(self, boardMax):
        ret = self.set_modbus_float(152, 1, [boardMax])
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_float(152, 1, [boardMax])
            if ret != 0:
                self.err_msg = "in set_flat_board_max() set main_zmc modbus_ieee(115) failed!"
                return self.err_msg
        return ret if ret == 0 else "设置 modbus_ieee(152) = {} 失败.".format(boardMax)

    def get_flat_board_max(self):
        ret, val = self.get_modbus_float(152, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret, val = self.get_modbus_float(152, 1)
            if ret != 0:
                self.err_msg = "in set_flat_board_max() set main_zmc modbus_ieee(115) failed!"
                return self.err_msg
        return val[0]

    def get_grade_state(self):
        ret, val = self.get_modbus_bit(65, 1)
        if ret != 0:
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(65, 1)
            if ret != 0:
                self.err_msg = "in get_grade_state() get main_zmc modbus_bit(535,1) failed!"
                return self.err_msg
        grateHidden = val[0]
        grateHidden = True if grateHidden == 1 else False
        return grateHidden

    def get_door_state(self):
        ret, val = self.get_modbus_bit(32, 1)
        if ret != 0:
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(32, 1)
            if ret != 0:
                self.err_msg = "in get_door_state() get main_zmc modbus_bit(32,1) failed!"
                return self.err_msg
        doorAlarm = val[0]
        doorAlarm = True if doorAlarm == 1 else False
        return doorAlarm

    def get_call_out_AGV_start(self):
        bitPos = [28, 29, 34, 35]
        bitValue = []
        for i in range(len(bitPos)):
            ret, val = self.get_modbus_bit(bitPos[i], 1)
            if ret != 0:
                gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(bitPos[i], 1)
            if ret != 0:
                self.err_msg = "in get_door_state() get main_zmc modbus_bit(32,1) failed!"
                return self.err_msg
            bitValue.append(val[0])
        return bitValue

    def set_call_out_AGV_start(self, bitStart):
        bitPos = [28, 29, 34, 35]
        for i in range(len(bitStart)):
            if bitStart[i] == 1:
                ret = self.set_modbus_bit(bitPos[i], 0)
                if ret != 0:
                    gevent.sleep(0.1)
                ret = self.set_modbus_bit(bitPos[i], 0)
                if ret != 0:
                    self.err_msg = "in get_door_state() get main_zmc modbus_bit(32,1) failed!"
                    return self.err_msg
        return 0

    def close_zmc_conn(self):
        """
        关闭zmc连接
        :return:
        """
        self.api.ZMC_Close.restype = c_int32
        self.api.ZMC_Close.argtype = c_void_p
        status = self.api.ZMC_Close(self.hRobot)
        return status

    def reconnect_main_zmc(self):
        try:
            self.close_zmc_conn()
        except Exception as e:
            errorInfo = "in CamZmc.reconnect_main_zmc() error: {}".format(str(e))
            print(errorInfo)
            self.logger.debug(errorInfo)
        status = self.connect_zmc()
        if status == 0:
            self.logger.debug("主控制器连接成功!")
            self.set_put_board_thickness_to_zmc()
        return "ok" if status == 0 else self.errorMsg

    def set_put_board_thickness_to_zmc(self):
        """
        设置叠板厚度
        :return:
        """
        data = self.db.get_board_thickness()[1]
        thicknessLv1 = int(data.get("thicknessMax1"))
        thicknessLv2 = int(data.get("thicknessMax2"))
        # 这里位置待定
        boardThicknessPos1 = BOARD_THICKNESS_LV_01  # LV1的叠板厚度设置
        boardThicknessPos2 = BOARD_THICKNESS_LV_02  # LV2的叠板厚度设置
        self.set_modbus_float(boardThicknessPos1, 1, [thicknessLv1])
        self.set_modbus_float(boardThicknessPos2, 1, [thicknessLv2])
        return "ok"

    def set_put_carrier_Size_to_zmc(self):
        """
        设置叠板厚度
        :return:
        """
        query = {
            "key": "1"
        }
        res, configParams = self.db.get_data_one(self.db.configParamsTable, query)
        if res != "ok":
            errorInfo = "in ConfigParams.reload_config_params() error: {}".format(configParams)
            print(errorInfo)
            self.logger.debug(errorInfo)
        else:
            carrierOneUpSize = configParams.get("carrierOneUpSize", 600)
            carrierOneDownSize = configParams.get("carrierOneDownSize", 300)
            carrierTwoUpSize = configParams.get("carrierTwoUpSize", 600)
            carrierTwoDownSize = configParams.get("carrierTwoDownSize", 300)
            # 这里位置待定
            self.set_modbus_float(90, 1, [carrierOneUpSize])
            self.set_modbus_float(92, 1, [carrierOneDownSize])
            self.set_modbus_float(94, 1, [carrierTwoUpSize])
            self.set_modbus_float(96, 1, [carrierTwoDownSize])
            return "ok"

    def web_request_update_board_thickness(self, newData):
        """
        界面上点击了保存放板高度
        :param newData:
        :return:
        """
        checkConnect = self.check_connect()
        if checkConnect:
            query = {"key": "1"}
            tableName = self.db.putBoardThicknessTable
            newValues = {
                "$set": newData
            }
            self.db.update_data(tableName, query, newValues)
            self.set_put_board_thickness_to_zmc()
            data = self.db.get_board_thickness()
            return "ok", [data]
        else:
            return "error", "设备无连接"

    def connect_zmc(self):
        """
        拍照控制器连接接口
        :param ip 设备的IP地址
        :return:
        """
        ip = self.ip
        if isinstance(ip, type(" ")):
            ip = ip.encode('ascii')
        self.api.ZMC_OpenEth.restype = c_int32
        self.api.ZMC_OpenEth.argtype = (c_char_p, c_void_p)
        status = self.api.ZMC_OpenEth(ip, byref(self.hRobot))
        if status == 0:
            self.errorMsg = ""
        else:
            self.errorMsg = "拍照控制器连接失败,{}".format(status)
        return status

    def check_connect(self):
        try:
            isConnect = self.get_modbus_bit(0, 1)[0]
            isConnect = True if isConnect == 0 else False
            return isConnect
        except Exception as e:
            errorInfo = "in CamZmc.check_connect() error : {}".format(str(e))
            print(errorInfo)
            self.logger.debug(errorInfo)
            return False

    # 直接获取所有的计数以及平板车物料状态
    def get_device_data_info(self):
        ret, val = self.get_modbus_float(110, 4)  # 其中中间三个没有用
        if ret != 0:
            gevent.sleep(0.1)
            ret, val = self.get_modbus_float(110, 4)
            if ret != 0:
                self.err_msg = "in get_device_data_info() get main_zmc mobus_ieee(110,7) failed!"
                return self.err_msg
        boardMaxLV, boardFinishedLv, boardMaxFlat, boardFinishedFlat = val

        # 然后是获取设备的物料满状态
        ret, val = self.get_modbus_bit(25, 1)
        if ret != 0:
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(25, 1)
            if ret != 0:
                self.err_msg = "in get_device_data_info() get main_zmc modbus_bit(25,2) failed!"
                return self.err_msg
        FullState = val[0]
        FullState = True if FullState == 1 else False

        # 获取是光栅被挡
        ret, val = self.get_modbus_bit(30, 1)
        if ret != 0:
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(30, 1)
            if ret != 0:
                self.err_msg = "in get_device_data_info() get main_zmc modbus_bit(25,2) failed!"
                return self.err_msg
        Locked = val[0]
        Locked = True if Locked == 1 else False
        return "ok", boardFinishedFlat, boardMaxFlat, boardFinishedLv, boardMaxLV, FullState

    # 拍照控制器设备启动
    def main_zmc_start(self):
        ret = self.set_modbus_bit(0, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(0, 1)
            if ret != 0:
                self.err_msg = "in cam_zmc_start() set cam_zmc bit(0) failed"
                return self.err_msg
        return ret if ret == 0 else "in main_zmc_start() 设置 modbus_bit(0) = 1 失败!"

    def cam_zmc_start_check(self):
        ret, res = self.get_modbus_bit(22, 1)
        if ret != 0:
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(22, 1)
            if ret != 0:
                self.err_msg = "in get_device_data_info() get main_zmc modbus_bit(22,1) failed!"
                return self.err_msg
        ret1, res1 = self.get_modbus_bit(23, 1)
        if ret1 != 0:
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(23, 1)
            if ret != 0:
                self.err_msg = "in get_device_data_info() get main_zmc modbus_bit(23,1) failed!"
                return self.err_msg
        return res, res1

    # 拍照控制器设备停止
    def main_zmc_stop(self):
        ret = self.set_modbus_bit(1, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(1, 1)
            if ret != 0:
                self.err_msg = "in cam_zmc_stop() set cam_zmc bit(1) failed"
                return self.err_msg
        return ret

    # 拍照控制器设备急停
    def cam_zmc_rs_stop(self):
        ret = self.set_modbus_bit(2, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(2, 1)
            if ret != 0:
                self.err_msg = "in cam_zmc_rs_stop() set cam_zmc bit(2) failed"
                return self.err_msg
        return ret

    # 拍照控制器设备复位
    def cam_zmc_reset(self):
        ret = self.set_modbus_bit(3, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(3, 1)
            if ret != 0:
                self.err_msg = "in cam_zmc_reset() set cam_zmc bit(3) failed!"
                return self.err_msg
        return ret

    def is_reset_state(self):
        """
        获取控制器是否是复位状态
        :return:
        """
        bitPos = 103
        bitCounts = 1
        ret, val = self.get_modbus_bit(bitPos, bitCounts)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(bitPos, bitCounts)
            if ret != 0:
                self.errorMsg = "in is_reset_state() 读取 modbus_bit ({}) 失败".format(bitPos)
                return -1, self.errorMsg
        return 0, val[0]

    # 拍照结果OK
    def img_result_ok(self):
        ret = self.set_modbus_bit(19, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(19, 1)
            if ret != 0:
                self.err_msg = "in img_result_ok() set cam_zmc bit(19) failed!"
                return self.err_msg
        return ret

    # 拍照结果NG
    def img_result_failed(self):
        ret = self.set_modbus_bit(20, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(20, 1)
            if ret != 0:
                self.err_msg = "in img_result_failed() set cam_zmc bit(20) failed!"
                return self.err_msg
        return ret

    # 门禁
    def door_result(self, val):
        ret = self.set_modbus_bit(200, int(val))
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(200, int(val))
            if ret != 0:
                self.err_msg = "in img_result_failed() set cam_zmc bit(200) failed!"
                return self.err_msg
        return ret

    # 重新拍照
    def re_get_pic(self):
        ret = self.set_modbus_bit(21, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(21, 1)
            if ret != 0:
                self.err_msg = "in re_get_pic() set cam_zmc bit(21) failed!"
                return self.err_msg
        return ret

    # 设备是否是运行状态
    def is_running(self):
        ret, val = self.get_modbus_bit(100, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(100, 1)
            if ret != 0:
                self.err_msg = "in is_running() get cam_zmc(100) failed!"
                return -1, self.err_msg
        return 0, val[0]

    # 设备是否是停止状态
    def is_stop_state(self):
        ret, val = self.get_modbus_bit(101, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(101, 1)
            if ret != 0:
                self.err_msg = "in is_stop_state() get cam_zmc(101) failed!"
                return -1, self.err_msg
        return 0, val[0]

    # 设备是否是急停状态
    def is_rs_stop(self):
        ret, val = self.get_modbus_bit(102, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(102, 1)
            if ret != 0:
                self.err_msg = "in is_rs_stop_state() get cam_zmc(102) failed!"
                return -1, self.err_msg
        return 0, val[0]

    # 设备是否在初始化过程中
    def is_init_state(self):
        ret, val = self.get_modbus_bit(104, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(104, 1)
            if ret != 0:
                self.err_msg = "in is_init_state() get cam_zmc(104) failed!"
                return -1, self.err_msg
        return 0, val[0]

    # 设备是否是超时待机状态
    def is_timeout_await(self):
        ret, val = self.get_modbus_bit(105, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(105, 1)
            if ret != 0:
                self.err_msg = "in is_timeout_await() get cam_zmc(105) failed!"
                return -1, self.err_msg
        return 0, val[0]

    # 等待拍照控制器复位,整体回零
    def wait_reset_home(self):
        while True:
            res, val = self.get_modbus_bit(103, 1)  # 获取设备复位的状态
            if res != 0:
                gevent.sleep(0.1)  # 休眠0.1秒之后再读一次
                res, val = self.get_modbus_bit(103, 1)  # 再读一遍
                if res != 0:
                    return -1
                # 如果返回1,表示正在复位,如果返回0,表示复位完成
            if val[0] == 1:
                gevent.sleep(0.1)
                continue
            elif val[0] == 0:
                return 0

    # 吹气阀1的控制,打开和关闭0和1,0表示关闭,1表示打开
    def blow_num1_handle(self, value):
        ret = self.set_output(0, value)
        if ret == -1:
            gevent.sleep(0.1)
            ret = self.set_output(0, value)
            if ret == -1:
                return self.err_msg
        return 0

    # 吹气阀2的控制,0表示关闭,1表示打开
    def blow_num2_handle(self, value):
        ret = self.set_output(1, value)
        if ret != 0:
            gevent.sleep(0.1)
            ret = self.set_output(1, value)
            if ret != 0:
                return self.err_msg
        return 0

    # 蜂鸣器报警打开和关闭
    def buzzer_alarm_handle(self, value):
        ret = self.set_output(3, value)
        if ret != 0:
            gevent.sleep(0.1)
            ret = self.set_output(3, value)
            if ret != 0:
                return self.err_msg
        return 0

    # 光源打开和关闭
    def light_source_handle(self, value):
        ret = self.set_output(6, value)
        if ret == -1:
            gevent.sleep(0.1)
            ret = self.set_output(3, value)
            if ret == -1:
                return self.err_msg
        return 0

    # 将数据写入到寄存器的表中
    def set_table(self, start, num, table):
        value = (c_float * num)(0)
        value[:] = table
        self.aux_api.ZAux_Direct_SetTable.restype = c_int32
        self.aux_api.ZAux_Direct_SetTable.argtype = (c_void_p, c_uint32, c_uint32, c_void_p)

        try:
            res = self.aux_api.ZAux_Direct_SetTable(self.hRobot, c_int32(start), c_int32(num), value)
        except Exception as e:
            res = -1
            print("in Zmc(set_table)  error: {}".format(e))
            self.logger.debug("in  Zmc(set_table), error: {}".format(e))

        if res != 0:
            self.err_msg = "ZAux_Direct_GetTable 执行失败"

        return res

    # 从底层读取台面补偿数据表.
    def get_table(self, start, num):
        value = (c_float * num)()
        self.aux_api.ZAux_Direct_GetTable.restype = c_int32
        self.aux_api.ZAux_Direct_GetTable.argtype = (c_void_p, c_int32, c_int32, c_void_p)
        try:
            res = self.aux_api.ZAux_Direct_GetTable(self.hRobot, c_int32(start), c_int32(num), value)
        except Exception as e:
            res = -1
            print("in Zmc(get_table)  error: {}".format(e))
            self.logger.debug("in  Zmc(get_table), error: {}".format(e))

        if res != 0:
            self.err_msg = "ZAux_Direct_GetTable 执行失败"

        return res, value[:]

    def resetRs(self):
        return self.set_modbus_bit(0, 1)

    def IO_state(self, num):
        cmd = "?in(" + str(num) + ")"
        return self.ZmcExecute(cmd)

    def IO_out_state(self, num):
        cmd = "?op(" + str(num) + ")"
        return self.ZmcExecute(cmd)

    def int2list(self, dec, num):
        # 只处理正整数
        assert dec >= 0
        assert num <= 32
        return list('{0:032b}'.format(dec)[::-1][:num])

    def get_io_res(self, cmd, num):
        res, val = self.ZmcExecute(cmd)
        if res != 0:
            return None
        val = val.decode()
        if val.find("\n") != -1:
            # print("before", val)
            val = val[:val.index("\n")]
            # print(val)
        res = self.int2list(int(val), num)
        return res

    # 获取输出口的状态
    def get_output(self, port):
        value = (c_uint32 * 1)()
        self.aux_api.ZAux_Direct_GetOp.restype = c_int32
        self.aux_api.ZAux_Direct_GetOp.argtype = (c_void_p, c_int32, c_void_p)
        try:
            res = self.aux_api.ZAux_Direct_GetOp(self.hRobot, c_int32(port), value)
        except Exception as e:
            res = -1
            print(e)

        if res != 0:
            self.err_msg = "in setOutput(): 输出口设置失败"
        return res, value[:][0]

    # 设置输出口的状态
    def set_output(self, port, value):
        self.aux_api.ZAux_Direct_SetOp.restype = c_int32
        self.aux_api.ZAux_Direct_SetOp.argtype = (c_void_p, c_int32, c_uint32)
        try:
            res = self.aux_api.ZAux_Direct_SetOp(self.hRobot, c_int32(port), c_uint32(value))
        except Exception as e:
            res = -1
            print(e)
        if res != 0:
            self.err_msg = "in setOutput(): 输出口设置失败"
        return res

    # 获取所有的IO口
    def get_all_io(self):
        try:
            in1 = self.get_io_res("?in(0,23)", 24)
            in2 = self.get_io_res("?in(48,63)", 16)
            out1 = self.get_io_res("?op(0,7)", 8)
            out2 = self.get_io_res("?op(48,63)", 16)
            return in1, in2, out1, out2
        except Exception as e:
            return None, None, None, None

    def get_lv_01_io_state(self):
        lv01 = self.get_io_res("?in(2,1)", 1)
        return lv01

    def getAllPosition(self, num):
        value = (c_float * num)()
        self.aux_api.ZAux_GetModbusDpos.restype = c_int32
        self.aux_api.ZAux_GetModbusDpos.argtype = (c_void_p, c_int32, c_void_p)
        try:
            res = self.aux_api.ZAux_GetModbusDpos(self.hRobot, c_int32(num), value)
        except Exception as e:
            res = -1
            print("in Zmc(getAllPosition)  error: {}".format(e))
            self.logger.debug("in  Zmc(getAllPosition), error: {}".format(e))
        if res != 0:
            self.err_msg = "in getAllPosition(): 获取6轴坐标失败"

        return res, value[:]

    # 从底层读取台面补偿数据表.
    def getPlatformTable(self, start):
        value = (c_float * 500)()
        self.api.ZAux_Direct_GetTable.restype = c_int32
        self.api.ZAux_Direct_GetTable.argtype = (c_void_p, c_uint32, c_uint32, c_void_p)
        try:
            res = self.api.ZAux_Direct_GetTable(self.hRobot, c_uint32(start), c_uint32(500), value)
        except Exception as e:
            res = -1
            print("in Zmc(getPlatformTable)  error: {}".format(e))
            self.logger.debug("in  Zmc(getPlatformTable), error: {}".format(e))

        if res != 0:
            self.err_msg = "ZAux_Direct_GetTable 执行失败"

        return res, value[:]

        # 设置输出口的状态

    def Connect(self, ip):
        if type(ip) == type(" "):
            ip = ip.encode('ascii')
        self.api.ZMC_OpenEth.restype = c_int64
        self.api.ZMC_OpenEth.argtype = (c_char_p, c_void_p)
        status = self.api.ZMC_OpenEth(ip, byref(self.hRobot))
        if status == 0:
            self.err_msg = ""
        else:
            self.err_msg = "连接失败"
        return status

    def Close(self):
        self.api.ZMC_Close.restype = c_int32
        self.api.ZMC_Close.argtype = c_void_p
        status = self.api.ZMC_Close(self.hRobot)
        return status

    def getStatus(self):
        loc = [0, 0, 0, 0]
        for i in range(0, 4):
            cmd = "?DPOS(%i)" % i
            loc[i] = float(self.ZmcExecute(cmd)[1])
        loc[0] = -loc[0]
        loc[3] = -loc[3]
        return loc

    def getX(self):
        cmd = "?DPOS(0)"
        try:
            loc = -float(self.ZmcExecute(cmd)[1])
        except Exception as e:
            print("in Zmc(getX)  error: {}".format(e))
            self.logger.debug("in  Zmc(getX), error: {}".format(e))
            return None
        return loc

    def getY(self):
        cmd = "?DPOS(1)"
        try:
            loc = float(self.ZmcExecute(cmd)[1])
        except Exception as e:
            print("in Zmc(getY)  error: {}".format(e))
            self.logger.debug("in  Zmc(getY), error: {}".format(e))
            return None
        return loc

    def getZ(self):
        cmd = "?DPOS(2)"
        ret, loc = self.ZmcExecute(cmd)
        if ret != 0:
            return None
        try:
            loc = float(loc)
        except Exception as e:
            print("in Zmc(getZ)  error: {}".format(e))
            self.logger.debug("in  Zmc(getZ), error: {}".format(e))
            return None
        return loc

    def getR(self):
        cmd = "?DPOS(3)"
        try:
            loc = -float(self.ZmcExecute(cmd)[1])
        except Exception as e:
            print("in Zmc(getR)  error: {}".format(e))
            self.logger.debug("in  Zmc(getR), error: {}".format(e))
            return None
        return loc

    def checkLoc(self, x, y, z, r, e=0.1):
        loc = self.getStatus()
        if x - e < loc[0] < x + e and y - e < loc[1] < y + e and z - e < loc[2] < z + e and r - e < loc[3] < r + e:
            return True
        else:
            return False

    def ZmcCancelOnline(self):
        self.api.ZMC_CancelOnline.restype = c_int32
        self.api.ZMC_CancelOnline.argtype = c_void_p
        status = self.api.ZMC_CancelOnline(self.hRobot)
        return status

    def ZmcGetModbusBit(self, start, num):
        ret = c_uint8()
        self.api.ZMC_Modbus_Get0x.restype = c_uint32
        self.api.ZMC_Modbus_Get0x.argtype = (c_void_p, c_int16, c_int16, c_void_p)
        try:
            value = self.api.ZMC_Modbus_Get0x(self.hRobot, c_int16(start), c_int16(num), byref(ret))
            return value, ret.value
        except Exception as e:
            value = -1
            print("in Zmc(ZmcGetModbusBit)  error: {}".format(e))
            self.logger.debug("in  Zmc(ZmcGetModbusBit), error: {}".format(e))
            return value, ret

    def ZmcDirectCommand(self, cmd):
        res = " " * 256
        self.api.ZMC_DirectCommand.restype = c_uint32
        self.api.ZMC_DirectCommand.argtype = (c_void_p, c_char_p, c_char_p, c_uint32)

        try:
            value = self.api.ZMC_DirectCommand(self.hRobot, c_char_p(cmd), c_char_p(res), 256)
        except Exception as e:  # todo
            print("in Zmc(ZmcDirectCommand)  error: {}".format(e))
            self.logger.debug("in  Zmc(ZmcDirectCommand), error: {}".format(e))
            value = -1
        return value, res.strip()[:-2]

    # 设置modbus位寄存器
    def set_modbus_bit(self, start, value):
        value = (c_uint8 * 1)(value)
        self.aux_api.ZAux_Modbus_Set0x.restype = c_int32
        self.aux_api.ZAux_Modbus_Set0x.argtype = (c_void_p, c_uint16, c_uint16, c_void_p)

        try:
            res = self.aux_api.ZAux_Modbus_Set0x(self.hRobot, c_uint16(start), c_uint16(1), value)
        except Exception as e:
            res = -1
            print("in Zmc(set_modbus_bit)  error: {}".format(e))
            self.logger.debug("in  Zmc(set_modbus_bit), error: {}".format(e))

        if res != 0:
            self.err_msg = "ZAux_Modbus_Set0x 执行失败"

        return res

    # 设置modbus字寄存器,目前是设置一个字节
    def set_modbus_byte(self, start, value):
        value = (c_uint16 * 1)(value)
        self.aux_api.ZAux_Modbus_Set4x.restype = c_int32
        self.aux_api.ZAux_Modbus_Set4x.argtype = (c_void_p, c_uint16, c_uint16, c_void_p)

        try:
            res = self.aux_api.ZAux_Modbus_Set4x(self.hRobot, c_uint16(start), c_uint16(1), value)
        except Exception as e:
            res = -1
            print("in Zmc(set_modbus_byte)  error: {}".format(e))
            self.logger.debug("in  Zmc(set_modbus_byte), error: {}".format(e))

        if res != 0:
            self.err_msg = "ZAux_Modbus_Set4x 执行失败"

        return res

    # 设置modbus浮点数寄存器,可以设置number个数据. modbus_iee
    def set_modbus_float(self, start, number, value):
        value = (c_float * number)(*value)
        self.aux_api.ZAux_Modbus_Set4x_Float.restype = c_int32
        self.aux_api.ZAux_Modbus_Set4x_Float.argtype = (c_void_p, c_uint16, c_uint16, c_void_p)

        try:
            res = self.aux_api.ZAux_Modbus_Set4x_Float(self.hRobot, c_uint16(start), c_uint16(number), value)
        except Exception as e:
            res = -1
            print("in Zmc(set_modbus_float)  error: {}".format(e))
            self.logger.debug("in  Zmc(set_modbus_float), error: {}".format(e))

        if res != 0:
            self.err_msg = "ZAux_Modbus_Set4x_Float 执行失败"

        return res

    # 读取modbus浮点数寄存器,可以读取多一个,以列表的形式返回.
    def get_modbus_float(self, start, num):
        value = (c_float * num)()
        self.aux_api.ZAux_Modbus_Get4x_Float.restype = c_int32
        self.aux_api.ZAux_Modbus_Get4x_Float.argtype = (c_void_p, c_uint16, c_uint16, c_void_p)

        try:
            res = self.aux_api.ZAux_Modbus_Get4x_Float(self.hRobot, c_uint16(start), c_uint16(num), value)
        except Exception as e:
            res = -1
            print("in Zmc(get_modbus_float)  error: {}".format(e))
            self.logger.debug("in  Zmc(get_modbus_float), error: {}".format(e))

        if res != 0:
            self.err_msg = "ZAux_Modbus_Get4x_Float 执行失败"
        return res, value[:]

    # 设置modbus浮点数寄存器,可以设置number个数据
    def set_modbus_long(self, start, number, value):
        value = (c_int32 * number)(*value)
        self.aux_api.ZAux_Modbus_Set4x_Long.restype = c_int32
        self.aux_api.ZAux_Modbus_Set4x_Long.argtype = (c_void_p, c_uint16, c_uint16, c_void_p)

        try:
            res = self.aux_api.ZAux_Modbus_Set4x_Long(self.hRobot, c_uint16(start), c_uint16(number), value)
        except Exception as e:
            res = -1
            print("in Zmc(set_modbus_long)  error: {}".format(e))
            self.logger.debug("in  Zmc(set_modbus_long), error: {}".format(e))

        if res != 0:
            self.err_msg = "ZAux_Modbus_Set4x_Long 执行失败"

        return res

    # 读取modbus浮点数寄存器,可以读取多一个,以列表的形式返回.
    def get_modbus_long(self, start, num):
        value = (c_int32 * num)()
        self.aux_api.ZAux_Modbus_Get4x_Long.restype = c_int32
        self.aux_api.ZAux_Modbus_Get4x_Long.argtype = (c_void_p, c_uint16, c_uint16, c_void_p)

        try:
            res = self.aux_api.ZAux_Modbus_Get4x_Long(self.hRobot, c_uint16(start), c_uint16(1), value)
        except Exception as e:
            res = -1
            print("in Zmc(get_modbus_long)  error: {}".format(e))
            self.logger.debug("in  Zmc(get_modbus_long), error: {}".format(e))

        if res != 0:
            self.err_msg = "ZAux_Modbus_Get4x_Long 执行失败"
        return res, value[:]

    # 读取modbus字寄存器,类型是无符号的短整型
    def get_modbus_byte(self, start, num):
        value = (c_uint16 * num)(0)
        self.aux_api.ZAux_Modbus_Get4x.restype = c_int32
        self.aux_api.ZAux_Modbus_Get4x.argtype = (c_void_p, c_uint16, c_uint16, c_void_p)

        try:
            res = self.aux_api.ZAux_Modbus_Get4x(self.hRobot, c_uint16(start), c_uint16(1), value)
        except Exception as e:
            res = -1
            print("in Zmc(get_modbus_byte)  error: {}".format(e))
            self.logger.debug("in  Zmc(get_modbus_byte), error: {}".format(e))

        if res != 0:
            self.err_msg = "ZAux_Modbus_Get4x 执行失败"
        return res, value[:]

    # 读取modbus位寄存器
    def get_modbus_bit(self, start, num):
        value = (c_uint8 * num)(0)
        self.aux_api.ZAux_Modbus_Get0x.restype = c_int32
        self.aux_api.ZAux_Modbus_Get0x.argtype = (c_void_p, c_uint16, c_uint16, c_void_p)

        try:
            res = self.aux_api.ZAux_Modbus_Get0x(self.hRobot, c_uint16(start), c_uint16(1), value)
        except Exception as e:
            res = -1
            print("in Zmc(get_modbus_bit)  error: {}".format(e))
            self.logger.debug("in  Zmc(get_modbus_bit), error: {}".format(e))

        if res != 0:
            self.err_msg = "ZAux_Modbus_Get0x 执行失败"
        return res, value[:]

    def ZmcExecute(self, cmd):
        # print("ZmcExecute",cmd)
        # self.buffer_size = 256* sizeof(c_char)
        # self.res_buffer = create_string_buffer(self.buffer_size)
        res = b" " * 256
        # res = res.encode('ascii')
        cmd = cmd.encode('ascii')
        # res = bytes(res, "ascii")
        self.api.ZMC_Execute.restype = c_uint32
        self.api.ZMC_Execute.argtype = (c_void_p, c_char_p, c_uint32, c_char_p, c_uint32)
        # cmd = bytes(cmd, "ascii")
        try:
            value = self.api.ZMC_Execute(self.hRobot, cmd, 1000, res, 256)
        except Exception as e:
            value = -1
        if value != 0:
            self.err_msg = "执行失败"
        return value, res.strip()[:-2]

    def ZmcExecuteRaw(self, cmd):
        res = " " * 256
        self.api.ZMC_Execute.restype = c_uint32
        self.api.ZMC_Execute.argtype = (c_void_p, c_char_p, c_uint32, c_char_p, c_uint32)

        try:
            value = self.api.ZMC_Execute(self.hRobot, c_char_p(cmd), 1000, c_char_p(res), 256)
        except Exception as e:  # todo
            print("in Zmc(ZmcExecuteRaw)  error: {}".format(e))
            self.logger.debug("in  Zmc(ZmcExecuteRaw), error: {}".format(e))
            value = -1

        return res.strip()

    def safeMove(self, cmd):
        if not self.IsRapidstop():
            return self.ZmcExecute(cmd)
        else:
            return -1, "急停"

    # 移动到绝对位置 注意 x轴反向了 r也反向了 顺时针为正
    def moveabs(self, loc):
        self.safeMove("base(0,1,2,3)")
        cmd = "moveabs(" + str("%.3f" % -loc[0]) + "," + str("%.3f" % loc[1]) + "," + str("%.3f" % loc[2]) + "," + str(
            "%.3f" % -loc[3]) + ")"
        return self.safeMove(cmd)

    def moveX(self, dis):
        self.safeMove("base(0)")
        cmd = "pmove(" + str("%.3f" % -dis) + ")"
        return self.safeMove(cmd)

    def moveY(self, dis):
        self.safeMove("base(1)")
        cmd = "pmove(" + str("%.3f" % dis) + ")"
        return self.safeMove(cmd)

    def moveZ(self, dis):
        self.safeMove("base(2)")
        cmd = "pmove(" + str("%.3f" % dis) + ")"
        return self.safeMove(cmd)

    def moveR(self, dis):
        self.safeMove("base(3)")
        cmd = "pmove(" + str("%.3f" % -dis) + ")"
        return self.safeMove(cmd)

    def moveXAbs(self, loc):
        self.safeMove("base(0)")
        cmd = "moveabs(" + str("%.3f" % -loc) + ")"
        return self.safeMove(cmd)

    def moveYAbs(self, loc):
        self.safeMove("base(1)")
        cmd = "moveabs(" + str("%.3f" % loc) + ")"
        return self.safeMove(cmd)

    def moveZAbs(self, loc):
        self.safeMove("base(2)")
        cmd = "moveabs(" + str("%.3f" % loc) + ")"
        return self.safeMove(cmd)

    def moveRAbs(self, loc):
        self.safeMove("base(3)")
        cmd = "moveabs(" + str("%.3f" % -loc) + ")"
        return self.safeMove(cmd)

    def waitidle(self, axis):
        cmd = "?idle(" + str(axis) + ")"
        while self.ZmcExecute(cmd)[1] != "-1":
            gevent.sleep(0.1)

    def set_speed(self, speed, accel, decel):
        try:
            speed_cmd = "speed=%i,%i,%i,%i" % (speed[0], speed[1], speed[2], speed[3])
            accel_cmd = "accel=%i,%i,%i,%i" % (accel[0], accel[1], accel[2], accel[3])
            decel_cmd = "decel=%i,%i,%i,%i" % (decel[0], decel[1], decel[2], decel[3])
        except Exception as e:
            print("in Zmc(set_speed)  error: {}".format(e))
            self.logger.debug("in  Zmc(set_speed), error: {}".format(e))
            return -1, "参数错误"
        try:
            ret, msg = self.ZmcExecute("base(0,1,2,3)")
            ret, msg = self.ZmcExecute(speed_cmd)
            ret, msg = self.ZmcExecute(accel_cmd)
            ret, msg = self.ZmcExecute(decel_cmd)
        except Exception as e:
            print("in Zmc(set_speed)  error: {}".format(e))
            self.logger.debug("in  Zmc(set_speed), error: {}".format(e))
            return -1, "速度设定失败"
        if ret != 0:
            return -1, "速度设定失败"
        return 0, "设置成功"

    def setout(self, num, onoff):
        cmd = "op(" + str(num) + "," + onoff + ")"
        return self.ZmcExecute(cmd)

    def get_out_status(self, id):
        return self.ZmcExecute("?out(%s)" % str(id))

    def rapidstop(self):
        # todo 应该用立即执行指令
        return self.ZmcExecute("rapidstop(3)")  # 急停清空消息队列

    def set_home_flag(self):
        return self.ZmcExecute("MODBUS_BIT(100) = 1")

    def get_home_flag(self):
        ret, val = self.ZmcExecute("?MODBUS_BIT(100)")
        if ret == -1:
            return -1, None
        else:
            if val == "1":
                # 回零
                return 0, True

            elif val == "0":
                # 未回零
                return 0, False

    def IsRapidstop(self):
        # 读取急停信号，1正常，0急停
        bret = False
        rs = self.ZmcExecute("?in(3)")[1]
        if rs == "1":
            bret = False
        elif rs == "0":
            bret = True
        return bret

    def getDis(self):
        try:
            dis = float(self.ZmcExecute("?ain(1)")[1])
        except Exception as e:
            print("in Zmc(getDis)  error: {}".format(e))
            self.logger.debug("in  Zmc(getDis), error: {}".format(e))
            return -1, str(e)
        dis = 24.3579 - 0.0147 * dis + 2
        return 0, dis

    def get_to_where_state(self):
        """
        获取设备去哪里的状态
        :return:
        """
        # 获取是否是去收料平台1的状态
        toLvBitPos1 = TO_LV_01  # 设置去lv1的bit标志位
        toLvBitPos2 = TO_LV_02  # 设置去lv2的bit标志位
        val1 = self.get_modbus_bit(toLvBitPos1, 1)[1][0]
        val2 = self.get_modbus_bit(toLvBitPos2, 1)[1][0]

        # 如果两个值都是1或者都是0,就设置放到收料平台1,然后返回给前端
        if (val1 == 1 and val2 == 1):
            self.set_put_board_to_LV1()
            toWhere = "收料平台1"
        elif val1 == 0 and val2 == 0:
            toWhere = "没有收料平台"
        elif val1 == 1 and val2 == 0:
            toWhere = "收料平台1"
        else:
            toWhere = "收料平台2"
        return toWhere

    def web_request_jacking_up_state_lv01(self):
        """
        界面上点击平台上升状态
        :return:
        """
        # 分批叠板计数清零
        # cp.reset_one_lot_board_count()
        ret = self.set_modbus_bit(61, 1)
        if ret != 0:
            return "error", ret
        ret = self.set_modbus_bit(60, 0)
        if ret != 0:
            return "error", ret
        fullState = self.get_Lv_full_state()
        return "ok", fullState

    def web_request_jacking_up_state_lv02(self):
        """
        界面上点击平台上升状态
        :return:
        """
        # 分批叠板计数清零
        # cp.reset_one_lot_board_count()
        ret = self.set_modbus_bit(63, 1)
        if ret != 0:
            return "error", ret
        ret = self.set_modbus_bit(62, 0)
        if ret != 0:
            return "error", ret
        fullState = self.get_Lv_full_state()
        return "ok", fullState

    def get_Lv_full_state(self):
        """
        获取LV是否满的状态
        :return:
        """
        val1 = self.get_modbus_bit(LV_01_FULL_STATE, 1)[1][0]
        val1_1 = self.get_modbus_bit(58, 1)[1][0]
        val2 = self.get_modbus_bit(LV_02_FULL_STATE, 1)[1][0]
        val2_1 = self.get_modbus_bit(59, 1)[1][0]
        fullStateLv01 = "已放满" if val1 == 1 else "空闲" if val1_1 == 1 else "放料平台离线"
        fullStateLv02 = "已放满" if val2 == 1 else "空闲" if val2_1 == 1 else "放料平台离线"
        return [fullStateLv01, fullStateLv02]

    def set_put_board_to_LV1(self):
        """
        设置放板位置位收料平台1
        :return:
        """
        toLvBitPos1 = TO_LV_01  # 设置去lv1的bit标志位
        toLvBitPos2 = TO_LV_02  # 设置去lv2的bit标志位
        toLvBitVal1 = 1
        toLvBitVal2 = 0
        ret1 = self.set_modbus_bit(toLvBitPos1, toLvBitVal1)
        if ret1 != 0:
            return "in set_put_board_to_LV1() 设置 modbus_bit({}) = {} 失败!".format(toLvBitPos1, toLvBitVal1)
        ret2 = self.set_modbus_bit(toLvBitPos2, toLvBitVal2)
        if ret2 != 0:
            return "in set_put_board_to_LV1() 设置 modbus_bit({}) = {} 失败!".format(toLvBitPos2, toLvBitVal2)
        return "ok"

    def set_put_board_to_LV2(self):
        """
        设置放板位置位收料平台1
        :return:
        """
        toLvBitPos1 = TO_LV_01  # 设置去lv1的bit标志位
        toLvBitPos2 = TO_LV_02  # 设置去lv2的bit标志位
        toLvBitVal1 = 0
        toLvBitVal2 = 1
        ret1 = self.set_modbus_bit(toLvBitPos1, toLvBitVal1)
        if ret1 != 0:
            return "in set_put_board_to_LV1() 设置 modbus_bit({}) = {} 失败!".format(toLvBitPos1, toLvBitVal1)
        ret2 = self.set_modbus_bit(toLvBitPos2, toLvBitVal2)
        if ret2 != 0:
            return "in set_put_board_to_LV1() 设置 modbus_bit({}) = {} 失败!".format(toLvBitPos2, toLvBitVal2)
        return "ok"

    def web_request_change_put_board_pos(self):
        """
        界面上点击了切换小车去向
        :return:
        """
        # 将板子的计数重新置位0,offset也置位0
        # cp.reset_one_lot_board_count()
        toWhere = self.get_to_where_state()
        if toWhere == "收料平台1":
            res = self.set_put_board_to_LV2()
            if res == "ok":
                return "ok", "收料平台2"
        else:
            res = self.set_put_board_to_LV1()
            if res == "ok":
                return "ok", "收料平台1"
        return "error", res

    def web_request_excep_reset(self):
        ret = self.set_modbus_bit(64, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret, val = self.set_modbus_bit(64, 1)
            if ret != 0:
                self.err_msg = "in set_modbus_bit() get main_zmc(42) failed!"
                return -1, self.err_msg

    def set_Lv1_full_quit(self):
        ret = self.set_modbus_bit(60, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret, val = self.set_modbus_bit(60, 1)
            if ret != 0:
                self.err_msg = "in set_modbus_bit() get main_zmc(42) failed!"
                return -1, self.err_msg
        ret = self.set_modbus_bit(61, 0)
        if ret != 0:
            return "error", ret
        return ret

    def set_Lv2_full_quit(self):
        ret = self.set_modbus_bit(62, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret, val = self.set_modbus_bit(62, 1)
            if ret != 0:
                self.err_msg = "in set_modbus_bit() get main_zmc(42) failed!"
                return -1, self.err_msg
        ret = self.set_modbus_bit(63, 0)
        if ret != 0:
            return "error", ret
        return ret

    def clear_grate_alarm(self):
        ret = self.set_modbus_bit(64, 1)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret, val = self.set_modbus_bit(64, 1)
            if ret != 0:
                self.err_msg = "in set_modbus_bit() get main_zmc(42) failed!"
                return -1, self.err_msg
        return ret

    def close_buzzer_alarm(self):
        """
        关闭蜂鸣器报警
        :return:
        """
        bitPos = 110
        bitValue = 0
        ret = self.set_modbus_bit(bitPos, bitValue)
        if ret != 0:
            gevent.sleep(0.5)
            ret = self.set_modbus_bit(bitPos, bitValue)
            if ret != 0:
                self.errorMsg = "in big_close_buzzer_alarm() 设置 modbus_bit({}) = {} 失败. ".format(bitPos, bitValue)
            return self.errorMsg
        return ret

    def get_pin_flag(self):
        bitVal = 72
        bitCounts = 1
        ret, val = self.get_modbus_bit(bitVal, bitCounts)
        if ret != 0:
            gevent.sleep(0.1)
            ret, val = self.get_modbus_bit(bitVal, bitCounts)
            if ret != 0:
                self.err_msg = "in get_pin_flag() get main_zmc get_pin_flag(50,1) failed!"
                return self.err_msg
        pinFlag = val[0]
        pinFlag = True if pinFlag == 0 else False
        return pinFlag

    def set_6pin_flag(self):
        """
        板子旋转,以图像的右侧的边作为偏移点
        :return:
        """
        bitPos = 72
        bitVal = 1
        ret = self.set_modbus_bit(bitPos, bitVal)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(bitPos, bitVal)
            if ret != 0:
                self.err_msg = "in set_6pin_flag() set main_zmc bit(50) failed!"
                return self.err_msg
        return ret

    def set_4pin_flag(self):
        """
        板子不旋转,以图像底边作为偏移点
        :return:
        """
        bitPos = 72
        bitVal = 0
        ret = self.set_modbus_bit(bitPos, bitVal)
        if ret != 0:
            # 重新试一次
            gevent.sleep(0.1)
            ret = self.set_modbus_bit(bitPos, bitVal)
            if ret != 0:
                self.err_msg = "in set_4pin_flag() set main_zmc bit(50) failed!"
                return self.err_msg
        return 0

    def get_bit_setYAdd_distance(self):
        toLvBitPos = 74  # 是否偏移的bit位置
        return self.get_modbus_bit(toLvBitPos, 1)[1][0]


if __name__ == '__main__':
    # 连接设备
    camZmc = MainZmc()
    ip = "192.168.1.16"
    status = camZmc.Connect(ip)
    # print(camZmc.cam_zmc_start_check())
    # print(camZmc.get_lv_01_io_state())
